package index

import (
	"bytes"
	"gitee.com/Cauchy_AQ/gokv/data"
	"github.com/Workiva/go-datastructures/slice/skip"
	"sort"
)

var (
	skipListLevel8  = uint8(0)
	skipListLevel16 = uint16(0)
	skipListLevel32 = uint32(0)
	skipListLevel64 = uint64(0)
)

type SkipList struct {
	sl *skip.SkipList
}

func NewSkipList() *SkipList {
	return &SkipList{
		sl: skip.New(skipListLevel16),
	}
}

// Put 向索引中存储 key 对应的数据位置信息
func (s *SkipList) Put(key []byte, pos *data.LogRecordPos) *data.LogRecordPos {
	item := &Item{key: key, pos: pos}
	overwritten := s.sl.Insert(item)
	if len(overwritten) > 0 && overwritten[0] != nil {
		return overwritten[0].(*Item).pos
	}
	return nil
}

// Get 根据 key 取出对于索引位置信息
func (s *SkipList) Get(key []byte) *data.LogRecordPos {
	item := &Item{key: key}
	overwritten := s.sl.Get(item)
	if len(overwritten) > 0 && overwritten[0] != nil {
		return overwritten[0].(*Item).pos
	}
	return nil
}

// Delete 根据 key 删除对于索引位置信息
func (s *SkipList) Delete(key []byte) (*data.LogRecordPos, bool) {
	item := &Item{key: key}
	overwritten := s.sl.Delete(item)
	if len(overwritten) > 0 && overwritten[0] != nil {
		return overwritten[0].(*Item).pos, true
	}
	return nil, false
}

// Iterator 索引迭代器
func (s *SkipList) Iterator(reverse bool) Iterator {
	return newSkipListIterator(s.sl, reverse)
}

// Size 获取数据数量大小
func (s *SkipList) Size() int {
	return int(s.sl.Len())
}

// Close 关闭索引
func (s *SkipList) Close() error {
	return nil
}

// skipListIterator SkipList 索引迭代器
type skipListIterator struct {
	currentIndex int
	reverse      bool
	values       []*Item
}

func newSkipListIterator(sl *skip.SkipList, reverse bool) *skipListIterator {
	var idx uint64
	if reverse {
		idx = sl.Len() - 1
	}
	values := make([]*Item, sl.Len())
	iter := sl.Iter(&Item{})
	for iter.Next() {
		values[idx] = iter.Value().(*Item)
		if reverse {
			idx--
		} else {
			idx++
		}
	}

	return &skipListIterator{
		currentIndex: 0,
		reverse:      reverse,
		values:       values,
	}
}

// Rewind 重新返回迭代起点
func (s *skipListIterator) Rewind() {
	s.currentIndex = 0
}

// Seek 根据传入 key 找到第一个大于（或小于）等于的目标 key，根据这个 key 开始遍历
func (s *skipListIterator) Seek(key []byte) {
	if s.reverse {
		// 反序，找到第一个小于等于 key 的位置
		s.currentIndex = sort.Search(len(s.values), func(i int) bool {
			return bytes.Compare(s.values[i].key, key) <= 0
		})
	} else {
		// 正序，找到第一个大于等于 key 的位置
		s.currentIndex = sort.Search(len(s.values), func(i int) bool {
			return bytes.Compare(s.values[i].key, key) >= 0
		})
	}
}

// Next 跳转到下一个 key
func (s *skipListIterator) Next() {
	s.currentIndex += 1
}

// Valid 是否有效，判断是否遍历完了 key
func (s *skipListIterator) Valid() bool {
	return s.currentIndex < len(s.values)
}

// Key 获取迭代器当前位置的 key
func (s *skipListIterator) Key() []byte {
	return s.values[s.currentIndex].key
}

// Value 获取当前迭代位置的索引位置信息
func (s *skipListIterator) Value() *data.LogRecordPos {
	return s.values[s.currentIndex].pos
}

// Close 关闭迭代器
func (s *skipListIterator) Close() {
	s.values = nil
}
